import {titleCase} from '@/utils/index'
import {trigger} from './config'
// 文件大小设置
const units = {
    KB: '1024',
    MB: '1024 / 1024',
    GB: '1024 / 1024 / 1024',
}

/**
 * @name: 生成js需要的数据
 * @description: 生成js需要的数据
 * @param {*} conf
 * @param {*} type 弹窗或表单
 * @return {*}
 */
export function makeUpJs(conf, type) {
    conf = JSON.parse(JSON.stringify(conf))
    const dataList = []
    const ruleList = []
    const optionsList = []
    const propsList = []
    const methodList = []
    const uploadVarList = []

    conf.fields.forEach((el) => {
        buildAttributes(
            el,
            dataList,
            ruleList,
            optionsList,
            methodList,
            propsList,
            uploadVarList
        )
    })

    const script = buildexport(
        conf,
        type,
        dataList.join('\n'),
        ruleList.join('\n'),
        optionsList.join('\n'),
        uploadVarList.join('\n'),
        propsList.join('\n'),
        methodList.join('\n')
    )

    return script
}

/**
 * @name: 生成参数
 * @description: 生成参数，包括表单数据表单验证数据，多选选项数据，上传数据等
 * @return {*}
 */
function buildAttributes(
    el,
    dataList,
    ruleList,
    optionsList,
    methodList,
    propsList,
    uploadVarList
) {
    buildData(el, dataList)
    buildRules(el, ruleList)

    if (el.options && el.options.length) {
        buildOptions(el, optionsList)
        if (el.dataType === 'dynamic') {
            const model = `${el.vModel}Options`
            const options = titleCase(model)
            buildOptionMethod(`get${options}`, model, methodList)
        }
    }

    if (el.props && el.props.props) {
        buildProps(el, propsList)
    }

    if (el.action && el.tag === 'el-upload') {
        uploadVarList.push(
            `
      // 上传请求路径
      const ${el.vModel}Action = ref('${el.action}')
      // 上传文件列表
      const ${el.vModel}fileList =  ref([])`
        )
        methodList.push(buildBeforeUpload(el))
        if (!el['auto-upload']) {
            methodList.push(buildSubmitUpload(el))
        }
    }

    if (el.children) {
        el.children.forEach((el2) => {
            buildAttributes(
                el2,
                dataList,
                ruleList,
                optionsList,
                methodList,
                propsList,
                uploadVarList
            )
        })
    }
}

/**
 * @name: 生成表单数据formData
 * @description: 生成表单数据formData
 * @param {*} conf
 * @param {*} dataList 数据列表
 * @return {*}
 */
function buildData(conf, dataList) {
    if (conf.vModel === undefined) return
    let defaultValue
    if (typeof conf.defaultValue === 'string' && !conf.multiple) {
        defaultValue = `'${conf.defaultValue}'`
    } else {
        defaultValue = `${JSON.stringify(conf.defaultValue)}`
    }
    dataList.push(`${conf.vModel}: ${defaultValue},`)
}

/**
 * @name: 生成表单验证数据rule
 * @description: 生成表单验证数据rule
 * @param {*} conf
 * @param {*} ruleList 验证数据列表
 * @return {*}
 */
function buildRules(conf, ruleList) {
    if (conf.vModel === undefined) return
    const rules = []
    if (trigger[conf.tag]) {
        if (conf.required) {
            const type = Array.isArray(conf.defaultValue) ? "type: 'array'," : ''
            let message = Array.isArray(conf.defaultValue)
                ? `请至少选择一个${conf.vModel}`
                : conf.placeholder
            if (message === undefined) message = `${conf.label}不能为空`
            rules.push(
                `{ required: true, ${type} message: '${message}', trigger: '${
                    trigger[conf.tag]
                }' }`
            )
        }
        if (conf.regList && Array.isArray(conf.regList)) {
            conf.regList.forEach((item) => {
                if (item.pattern) {
                    rules.push(
                        `{ pattern: new RegExp(${item.pattern}), message: '${
                            item.message
                        }', trigger: '${trigger[conf.tag]}' }`
                    )
                }
            })
        }
        ruleList.push(`${conf.vModel}: [${rules.join(',')}],`)
    }
}

/**
 * @name: 生成选项数据
 * @description: 生成选项数据，单选多选下拉等
 * @param {*} conf
 * @param {*} optionsList 选项数据列表
 * @return {*}
 */
function buildOptions(conf, optionsList) {
    if (conf.vModel === undefined) return
    if (conf.dataType === 'dynamic') {
        conf.options = []
    }
    const str = `const ${conf.vModel}Options = ref(${JSON.stringify(conf.options)})`
    optionsList.push(str)
}

/**
 * @name: 生成方法
 * @description: 生成方法
 * @param {*} methodName 方法名
 * @param {*} model
 * @param {*} methodList 方法列表
 * @return {*}
 */
function buildOptionMethod(methodName, model, methodList) {
    const str = `function ${methodName}() {
    // TODO 发起请求获取数据
    ${model}.value
  }`
    methodList.push(str)
}

/**
 * @name: 生成表单组件需要的props设置
 * @description: 生成表单组件需要的props设置，如；级联组件
 * @param {*} conf
 * @param {*} propsList
 * @return {*}
 */
function buildProps(conf, propsList) {
    if (conf.dataType === 'dynamic') {
        conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey)
        conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey)
        conf.childrenKey !== 'children' &&
        (conf.props.props.children = conf.childrenKey)
    }
    const str = `
  // props设置
  const ${conf.vModel}Props = ref(${JSON.stringify(conf.props.props)})`
    propsList.push(str)
}

/**
 * @name: 生成上传组件的相关内容
 * @description: 生成上传组件的相关内容
 * @param {*} conf
 * @return {*}
 */
function buildBeforeUpload(conf) {
    const unitNum = units[conf.sizeUnit]
    let rightSizeCode = ''
    let acceptCode = ''
    const returnList = []
    if (conf.fileSize) {
        rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize}
    if(!isRightSize){
      proxy.$modal.msgError('文件大小超过 ${conf.fileSize}${conf.sizeUnit}')
    }`
        returnList.push('isRightSize')
    }
    if (conf.accept) {
        acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type)
    if(!isAccept){
      proxy.$modal.msgError('应该选择${conf.accept}类型的文件')
    }`
        returnList.push('isAccept')
    }
    const str = `
  /**
   * @name: 上传之前的文件判断
   * @description: 上传之前的文件判断，判断文件大小文件类型等
   * @param {*} file
   * @return {*}
   */  
  function ${conf.vModel}BeforeUpload(file) {
    ${rightSizeCode}
    ${acceptCode}
    return ${returnList.join('&&')}
  }`
    return returnList.length ? str : ''
}

/**
 * @name: 生成提交表单方法
 * @description: 生成提交表单方法
 * @param {Object} conf vModel 表单ref
 * @return {*}
 */
function buildSubmitUpload(conf) {
    const str = `function submitUpload() {
    this.$refs['${conf.vModel}'].submit()
  }`
    return str
}

/**
 * @name: 组装js代码
 * @description: 组装js代码方法
 * @return {*}
 */
function buildexport(
    conf,
    type,
    data,
    rules,
    selectOptions,
    uploadVar,
    props,
    methods
) {
    let str = `
    const { proxy } = getCurrentInstance()
    const ${conf.formRef} = ref()
    const data = reactive({
      ${conf.formModel}: {
        ${data}
      },
      ${conf.formRules}: {
        ${rules}
      }
    })

    const {${conf.formModel}, ${conf.formRules}} = toRefs(data)

    ${selectOptions}

    ${uploadVar}

    ${props}

    ${methods}
  `

    if (type === 'dialog') {
        str += `
      // 弹窗设置
      const dialogVisible = defineModel()
      // 弹窗确认回调
      const emit = defineEmits(['confirm'])
      /**
       * @name: 弹窗打开后执行
       * @description: 弹窗打开后执行方法
       * @return {*}
       */
      function onOpen(){

      }
      /**
       * @name: 弹窗关闭时执行
       * @description: 弹窗关闭方法，重置表单
       * @return {*}
       */
      function onClose(){
        ${conf.formRef}.value.resetFields()
      }
      /**
       * @name: 弹窗取消
       * @description: 弹窗取消方法
       * @return {*}
       */
      function close(){
        dialogVisible.value = false
      }
      /**
       * @name: 弹窗表单提交
       * @description: 弹窗表单提交方法
       * @return {*}
       */
      function handelConfirm(){
        ${conf.formRef}.value.validate((valid) => {
          if (!valid) return
          // TODO 提交表单

          close()
          // 回调父级组件
          emit('confirm')
        })
      }
    `
    } else {
        str += `
    /**
     * @name: 表单提交
     * @description: 表单提交方法
     * @return {*}
     */
    function submitForm() {
      ${conf.formRef}.value.validate((valid) => {
        if (!valid) return
        // TODO 提交表单
      })
    }
    /**
     * @name: 表单重置
     * @description: 表单重置方法
     * @return {*}
     */
    function resetForm() {
      ${conf.formRef}.value.resetFields()
    }
    `
    }
    return str
}
